// ========================================================
// GREATEST COMMON DIVISOR
//
// Calculates GCD(84, 30)
//
// x10 = first function argument
// x11 = second function argument
// x12 = returned GCD
// x1  = return address
// ========================================================


start:

        addi  x10, x0, 84         // First number
        addi  x11, x0, 30         // Second number

        jal   x1, FindGCD          // Call GCD function

        cout  << "GCD of 84 and 30 = " << x12 << endl

        jal   x0, EndProgram       // Skip over function code


// --------------------------------------------------------
// FindGCD function
//
// Uses the subtraction form of Euclid's algorithm.
//
// Input:
//   x10 = first positive number
//   x11 = second positive number
//
// Output:
//   x12 = greatest common divisor
// --------------------------------------------------------

FindGCD:
        beq   x10, x0, FirstZero   // Handle first value being zero
        beq   x11, x0, SecondZero  // Handle second value being zero

GCDLoop:
        beq   x10, x11, GCDFound   // Equal values contain the GCD
        blt   x10, x11, SubtractA  // If x10 < x11, change x11

        sub   x10, x10, x11        // x10 = x10 - x11
        jal   x0, GCDLoop

SubtractA:
        sub   x11, x11, x10        // x11 = x11 - x10
        jal   x0, GCDLoop

FirstZero:
        add   x12, x11, x0         // Return second value
        jalr  x0, 0(x1)

SecondZero:
        add   x12, x10, x0         // Return first value
        jalr  x0, 0(x1)

GCDFound:
        add   x12, x10, x0         // Copy GCD into return register
        jalr  x0, 0(x1)            // Return to caller

EndProgram:
